package com.sean.gulimall.product.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sean.common.constant.ProductConstant;
import com.sean.common.utils.PageUtils;
import com.sean.common.utils.Query;
import com.sean.common.utils.R;
import com.sean.gulimall.product.dao.AttrDao;
import com.sean.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.sean.gulimall.product.entity.AttrEntity;
import com.sean.gulimall.product.entity.AttrGroupEntity;
import com.sean.gulimall.product.entity.CategoryEntity;
import com.sean.gulimall.product.service.AttrAttrgroupRelationService;
import com.sean.gulimall.product.service.AttrGroupService;
import com.sean.gulimall.product.service.AttrService;
import com.sean.gulimall.product.service.CategoryService;
import com.sean.gulimall.product.vo.AttrResponseVo;
import com.sean.gulimall.product.vo.AttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationService attrgroupRelationService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private AttrGroupService attrGroupService;

    @Resource
    private AttrDao attrDao;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void saveAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        //保存属性
        BeanUtils.copyProperties(attr,attrEntity);
        this.save(attrEntity);

        // 销售属性不需要保存分组关系，如果前端传递过来的属性分组Id为空也不需要添加属性分组
        if (attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId() != null)
        {
          // 保存属性分组关联关系
          AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
          relationEntity.setAttrGroupId(attr.getAttrGroupId());
          relationEntity.setAttrId(attrEntity.getAttrId());
          attrgroupRelationService.save(relationEntity);
        }
    }

    @Override
    public PageUtils queryAttrPageByCatelogId(Map<String, Object> params, Long categoryId,int type) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(AttrEntity::getAttrType,type);
        if(categoryId != 0)
        {
            queryWrapper.lambda().eq(AttrEntity::getCatelogId,categoryId);

        }
        //模糊查询
        String key =(String) params.get("key");
        if(!StrUtil.isEmpty(key))
        {
            queryWrapper.lambda().and((wrapper)->{
                wrapper.eq(AttrEntity::getAttrId,key)
                        .or()
                        .like(AttrEntity::getAttrName,key);
            });
        }

        IPage page = this.page(new Query<AttrEntity>().getPage(params),queryWrapper);
        PageUtils pageUtils = new PageUtils(page);
        //需要返回属性分组信息
        List<AttrEntity> records = page.getRecords();

        List<AttrResponseVo> responseVoList = records.stream().map(attrEntity -> {
            AttrResponseVo responseVo = new AttrResponseVo();
            BeanUtils.copyProperties(attrEntity,responseVo);
            //查询分组
            if (attrEntity.getCatelogId() != null) {
                CategoryEntity categoryEntity = categoryService.getById(attrEntity.getCatelogId());
                responseVo.setCatelogName(categoryEntity.getName());
            }
            AttrAttrgroupRelationEntity relationEntity = attrgroupRelationService.getOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId()));
            if (relationEntity != null) {
                AttrGroupEntity attrGroupEntity = attrGroupService.getById(relationEntity.getAttrGroupId());
                if(attrGroupEntity != null)
                {
                    responseVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            return responseVo;

        }).collect(Collectors.toList());

        pageUtils.setList(responseVoList);
        return pageUtils;
    }

    @Override
    public AttrResponseVo getAttrAllInfo(Long attrId) {
        AttrEntity attrEntity = this.getById(attrId);
        AttrResponseVo responseVo = new AttrResponseVo();
        BeanUtils.copyProperties(attrEntity,responseVo);

        //获取属性分组Id
        if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
        {
            AttrAttrgroupRelationEntity relationEntity = attrgroupRelationService.getOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
            AttrGroupEntity groupEntity = attrGroupService.getById(relationEntity.getAttrGroupId());
            if(groupEntity != null)
            {
                responseVo.setGroupName(groupEntity.getAttrGroupName());
                responseVo.setAttrGroupId(groupEntity.getAttrGroupId());
            }
        }
        //获取分类路径catelogPath catelogId=255
        List<Long> cateLogIdList = new ArrayList<>();
        cateLogIdList = this.getCateLogPath(attrEntity.getCatelogId(),cateLogIdList);

        Collections.reverse(cateLogIdList);
        Long[] cateLogPath = cateLogIdList.toArray(new Long[cateLogIdList.size()]);
        responseVo.setCatelogPath(cateLogPath);
        return responseVo;
    }

    private List<Long> getCateLogPath(Long cateLogId,List<Long> cateLogPathList)
    {
        cateLogPathList.add(cateLogId);

        CategoryEntity categoryEntity = categoryService.getById(cateLogId);
        if(categoryEntity != null && categoryEntity.getParentCid() != 0)
        {
            cateLogPathList = getCateLogPath(categoryEntity.getParentCid(),cateLogPathList);
        }
        return cateLogPathList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAttr(AttrVo attr) {
        //1.首先更新属性
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        this.updateById(attrEntity);

        if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
        {
            //2.更新属性关联
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attr.getAttrId());
            LambdaUpdateWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId());

            long count = attrgroupRelationService.count(wrapper);
            if(count > 0)
            {
                attrgroupRelationService.update(relationEntity,wrapper);
            }else {
                attrgroupRelationService.save(relationEntity);
            }
        }
    }

    @Override
    public R removeAttrByIds(List<Long> attrIds) {
        //需要判断如果有和属性分组关联的属性不能删除
       for(Long attrId : attrIds)
       {
           AttrEntity attrEntity = this.getById(attrId);
           long count = attrgroupRelationService.count(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
           if(count > 0)
           {
               return R.error("请先解除属性:"+attrEntity.getAttrName()+",与属性分组的关联关系");
           }
       }
       this.removeByIds(attrIds);
       return R.ok();
    }

    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {

        return  attrDao.getAttrByAttrGroupId(attrGroupId);
    }
}